

// require('../../less/selector.less');





/*
[{
	tpl: //..,
	width: 20%,

}, ]

eg.
let select = new Selector([{
	width: '50%',
	tpl: require('tpl1.ejs');
	//tpl中必须全是 li, 可以不传tpl, 通过beforeShow回调中arguments设置(arguments对应每个选择ul,)
	//this.setOpt(ul, tpl);
	// 然后下面设置选择
	//this.setByNum(ul, 0); 设置选择第0个
	//this.setByVal(ul, 'abc') 设置data-value是abc的选中
}, {
	tpl: require('tpl2.ejs');
}, ...])

select.onsure(function(li1, li2, ...) {
	// li1, li2分别是第1和第2个tpl中被选中的li节点
})
.onchange(function(ul, li, uls) {
	// ul 发生change的ul
	// li 发生change之后选中的li
	// uls 所有的ul
})


*/
function Selector(chooseType) {
	this.chooseType = chooseType || {};
	this._init();
}


var fn = Selector.prototype = {
	constructor: Selector,

	_init() {
		this._getElement();
		let chooseType = this.chooseType;

		let html = chooseType.map(e => {
			return `<ul>${e.tpl || ''}</ul>`;
		}).join('');

		html += `<div></div>`;

		this.body.innerHTML = html;
		this.uls = slice.call(this.body.querySelectorAll('ul'), 0);

		this.initUls();
	},

	initUls() {
		this.uls.forEach((ul, i) => setcss(ul, this.chooseType[i]));
	},

	setByNum(ul, n) {
		n = n || 0;
		let lis = ul.getElementsByTagName('li');
		n = Math.abs(Math.min(n, lis.length));
		let li = lis[n];
		slice.call(lis, 0).forEach((li, i) => {
			if(n == i) {
				addCls(li, 'choose');
				if(li && li.dataset.choose)
					li.innerHTML = li.dataset.choose;
				ul.n = i;
				ul.y = (1-i)*this.optHeight;
				ul.style.transform = `translate3d(0, ${ul.y}px, 0)`;
				ul.style.webkitTransform = `translate3d(0, ${ul.y}px, 0)`;
			} else {
				rmCls(li, 'choose');
				li.dataset.default && (li.innerHTML = li.dataset.default);
			}
		});
		return this;
	},

	setByVal(ul, v) {
		let lis = ul.getElementsByTagName('li');

		slice.call(lis, 0).forEach((li, i) => {
			if(li.dataset.value == v) {
				// console.log(li.dataset.value)
				addCls(li, 'choose');
				if(li && li.dataset.choose)
					li.innerHTML = li.dataset.choose;
				ul.n = i;
				ul.y = (1-i)*this.optHeight;
				ul.style.transform = `translate3d(0, ${ul.y}px, 0)`;
				ul.style.webkitTransform = `translate3d(0, ${ul.y}px, 0)`;
			} else {
				rmCls(li, 'choose');
				li.dataset.default && (li.innerHTML = li.dataset.default);
			}
		})
		return this;
	},

	setOpt(ul, tpl, attr) {
		ul.innerHTML = tpl;
		if(typeof attr === 'string') {
			let lis = ul.getElementsByTagName('li');
			for(let i = 0, m = lis.length; i < m; i++) {
				if(lis[i].getAttribute(attr) != null) {
					this.setByNum(ul, i);
					break;
				}
			}
		}
		return this;
	},

	show() {
		document.body.appendChild(this.mask);
		document.body.appendChild(this.box);


		bind(document, 'touchstart', stopDefault);

		setTimeout(() => {
			addCls(this.mask, 'show');
			addCls(this.box, 'show');

			this._convertLayout();
			if( !this.optHeight ) {
				this.optHeight = this.uls[0].parentNode.offsetHeight*2/7;	//100px:350px
				// let li = this.uls[0].getElementsByTagName('li');
				// this.optHeight = 100;//li && li.offsetHeight || 100;
				// setTimeout(() => {
				// 	alert(ul.children[0].offsetHeight)
				// }, 3000)
			}
			if(this._beforeShow) {
				this.uls.forEach(ul => {
					ul.style.transitionDuration = 'initial';
					ul.style.webkitTransitionDuration = 'initial';
				})
				this._beforeShow(...this.uls);
				setTimeout(() => {
					this.uls.forEach(ul => {
						ul.style.transitionDuration = '0.5s';
						ul.style.webkitTransitionDuration = '0.5s';
					})
				}, 0)
			}
		}, 0)
		return this;
	},

	beforeShow(fn) {
		this._beforeShow = fn;
		return this;
	},

	_convertLayout() {
		this.uls.forEach(ul => {
			ul.style.left = `${ul.offsetLeft}px`;
			ul.style.top = `${ul.offsetTop}px`;
		})
		this.uls.forEach(ul => {
			ul.style.position = 'absolute';
			ul.style.margin = 0;
		})

		this._convertLayout = () => {};
	},

	hide() {
		rmCls(this.mask, 'show');
		rmCls(this.box, 'show');

		unbind(document, 'touchstart', stopDefault);
		return this;
	},


	oncancel(fn) {
		this._cancel = fn;
		return this;
	},

	onsure(fn) {
		this._onsure = fn;
		return this;
	},

	onchange(fn) {
		this._onchange = fn;
		return this;
	},

	_afterHide() {
		document.body.removeChild(this.mask);
		document.body.removeChild(this.box);
	},

	afterShow(fn) {
		this._afterShow = fn;
		return this;
	},

	// _stopSelect(ul) {
		// let n = Math.abs( (ul.y - 100)/100 | 0 );
		// let li = ul.children[n]
		// addCls(li, 'choose');
	// },

	_getElement() {
		var mask = document.createElement('div');
		mask.className = 'selector-mask';


		var box = document.createElement('div');
		box.className = 'selector-box';

		box.innerHTML = `
			<div class="head">
				<div class="cancel">取消</div>
				<div class="sure">确定</div>
			</div>
			<div class="body"></div>
		`



		this.mask = mask;
		this.box = box;
		this.head = box.querySelector('.head');
		this.body = box.querySelector('.body');
		bind(this.mask, 'click', () => {
			this.hide();
			this._cancel && this._cancel();
			// this.setAllDefault();
		});
		bind(this.mask, 'transitionend', () => {
			if( hasCls(this.mask, 'show') ) {
				this._afterShow && this._afterShow.call(this, ...this.uls);
			} else {
				this._afterHide();
			}
		})
		bind(this.head, 'click', e => {
			switch( e.target.className ) {
				case 'cancel':
					this.hide();
					this._cancel && this._cancel();
					// this.setAllDefault();
					break;
				case 'sure':
					this._onsure && this._onsure.apply(this, this.uls.map(ul => ul.children[ul.n]));
					this.hide();
			}
		})

		let ul, start, height, velocity;
		let timeStart
		bind(this.body, 'touchstart', e => {

			if( ~['UL', 'LI'].indexOf(e.target.nodeName) ) {
				start = e.touches[0].clientY;
				timeStart = Date.now();

				ul = e.target.nodeName === 'UL' ? e.target : e.target.parentNode;
				ul.style.transitionDuration = 'initial';
				ul.style.webkitTransitionDuration = 'initial';
				height = ul.offsetHeight - this.optHeight*3;
				bind.call(this, document, 'touchmove', documentMove);
				bind.call(this, document, 'touchend', documentEnd);
			}

		});

		let self = this;
		function documentEnd(e) {
			if(ul) {
				let n = Math.round(ul.y/self.optHeight);

				let len = ul.children.length;			//当前正在滑动ul中选项个数

				let threshold = 0.05;					//速度阈值
				if( Math.abs(velocity) >= threshold ) {
					// console.log(Math.abs(velocity))
					let m = inertia(velocity);
					// console.log(m)
					n += m;
					n = Math.max(Math.min(n, 1), 1 - (len - 1) )
				}
				velocity = 0;

				ul.n = Math.min(Math.max(1 - n, 0), len - 1);
				ul.y = n*self.optHeight;
				ul.style.transitionDuration = '0.5s';
				ul.style.webkitTransitionDuration = '0.5s';
				ul.style.transform = `translate3d(0, ${ul.y}px, 0)`;
				ul.style.webkitTransform = `translate3d(0, ${ul.y}px, 0)`;

				self._onchange && self._onchange(ul, ul.children[ul.n], self.uls);

				let li = ul.children[ul.n];
				addCls(li, 'choose');
				if(li.dataset.choose)
					li.innerHTML = li.dataset.choose;


			}
			unbind(document, 'touchmove', documentMove);
			unbind(document, 'touchend', documentEnd);
		}

		function documentMove(e) {
			let delta = e.touches[0].clientY - (start || 0);
			velocity = delta/(Date.now() - timeStart);

			start = e.touches[0].clientY;
			ul.y = Math.min( (ul.y || 0) + delta, self.optHeight*1.5 - 1 );
			ul.y = Math.max( ul.y, -height + self.optHeight*1.5 + 1 )
			// console.log(self.optHeight)

			ul.style.transform = `translate3d(0, ${ul.y}px, 0)`;
			ul.style.webkitTransform = `translate3d(0, ${ul.y}px, 0)`;

			slice.call(ul.children, 0).forEach(e => {
				rmCls(e, 'choose');
				e.dataset.default && (e.innerHTML = e.dataset.default)
			})
		}


		bind(this.body, 'transitionend', e => {
			if(e.target === ul) {
				// 必须在touchend触发, 否则多个分类选项的时候易出bug
				// let li = ul.children[ul.n];
				// addCls(li, 'choose');
				// if(li.dataset.choose)
				// 	li.innerHTML = li.dataset.choose;

			}
		})
	}

}


let slice = [].slice;


function bind(e, type, fn) {
	return e.addEventListener(type, fn, false);
}

function unbind(e, type, fn) {
	return e.removeEventListener(type, fn, false);
}

function addCls(e, cls) {
	if(e.className) {
		if( ~e.className.indexOf(cls) ) {
			rmCls(e, cls);
		}
		e.className += ' ' + cls;
	} else {
		e.className = cls;
	}
}

function hasCls(e, cls) {
	if( e.className ) {
		return e.className.split(/\s+/).some(v => v === cls);
	}
}

function rmCls(e, cls) {
	if( e.className ) {
		e.className = e.className.split(/\s+/).filter(v => v !== cls).join(' ');
	}
}

function stopDefault(e) {
	e.preventDefault();
}

function setcss(ul, obj) {
	for(let name in obj) {
		if(name !== 'tpl') {
			ul.style[name] = obj[name];
		}
	}
	if( !obj.hasOwnProperty('width') )
		ul.style.width = '20%';
	if( !obj.hasOwnProperty('textAlign') )
		ul.style.textAlign = 'center';
}

function inertia(v) {
	let flag = v > 0 ? 1 : -1;
	v = Math.abs(v);
	if(v > 1.5) {
		return flag*20;
	} else if(v > 1) {
		return flag*15;
	} else if(v > 0.6) {
		return flag*10;
	} else if(v > 0.4) {
		return flag*6;
	} else if(v > 0.3) {
		return flag*4;
	} else if(v > 0.2) {
		return flag*3;
	} else if(v > 0.1) {
		return flag*2;
	} else if(v > 0.07) {
		return flag*2
	} else if(v > 0.05) {
		return flag*1;
	} else {
		return flag;
	}
}


module.exports = Selector;
